package com.bailan.foreat.service.impl;

import com.bailan.foreat.entity.Product;
import com.bailan.foreat.entity.Store;
import com.bailan.foreat.exception.CartException;
import com.bailan.foreat.mapper.ProductMapper;
import com.bailan.foreat.mapper.StoreMapper;
import com.bailan.foreat.service.CartService;
import com.bailan.foreat.vo.CartAll;
import com.bailan.foreat.vo.CartItem;
import com.bailan.foreat.vo.CartVo;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private StoreMapper storeMapper;

    @Override
    public void addCart(Integer userId, Integer productId) {
        Product product = productMapper.selectById(productId);
        CartItem cartItem = new CartItem(productId, product.getProductName(), product.getProductImg(), product.getProductPrice(), 1, product.getProductPrice(),product.getStockCount());
        HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
        Object o = opsForHash.get(userId + "", productId + "");
        //判断购物车是否存在该商品
        if (o != null) {
            CartItem oldCartItem = (CartItem) o;
            cartItem.setBuyCount(oldCartItem.getBuyCount() + 1);
            cartItem.setSumPrice(oldCartItem.getSumPrice().add(product.getProductPrice()));
        }
        if (product.getStockCount() < cartItem.getBuyCount() ){
            throw new CartException("商品库存量不足");
        }
        opsForHash.put(userId + "", productId + "", cartItem);

    }

    @Override
    public List<Object> getAllCartItems(Integer userId) {
        HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
        List<Object> objectList = opsForHash.values(userId + "");
        return objectList;
    }

    @Override
    public List<CartVo> getAllCartVos(Integer userId) {
        List<Object> cartItems = getAllCartItems(userId);
        HashMap<Integer, List<CartItem>> map = new HashMap<>();
        for (Object o : cartItems) {
            CartItem cartItem = (CartItem) o;
            Product product = productMapper.selectById(cartItem.getProductId());
            Integer storeId = product.getStoreId();
            if (map.containsKey(storeId)) {
                map.get(storeId).add(cartItem);
            } else {
                List<CartItem> cartItemList = new ArrayList<>();
                cartItemList.add(cartItem);
                map.put(storeId, cartItemList);
            }
        }
        List<CartVo> cartVoList = new ArrayList<>();
        for (Map.Entry<Integer, List<CartItem>> entry : map.entrySet()) {
            CartVo cartVo = new CartVo();
            cartVo.setStoreId(entry.getKey());
            cartVo.setCartItemList(entry.getValue());

            Store store = storeMapper.selectById(entry.getKey());
            cartVo.setStoreName(store.getStoreName());
            cartVo.setStoreImg(store.getStoreImg());

            cartVoList.add(cartVo);
        }
        return cartVoList;
    }

    @Override
    public String updateBuyCount(Integer userId, Integer productId, Integer buyCount) {
        HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
        CartItem cartItem = (CartItem) opsForHash.get(userId + "", productId + "");
        Product product = productMapper.selectById(productId);
        if (product.getStockCount() < buyCount){
            throw new CartException("商品库存不足！");
        }
        if (buyCount > 0) {
            //1.BuyCount > 0
            cartItem.setBuyCount(buyCount);
            cartItem.setSumPrice((cartItem.getProductPrice()).multiply(new BigDecimal(buyCount)));
            opsForHash.put(userId + "", productId + "", cartItem);
            return "修改成功！";
        }else{
            //2.BuyCount <= 0，删除
            if (buyCount <= 0) {
                opsForHash.delete(userId + "", productId + "");
                return "删除成功！";
            }
        }
        return "未知错误！";

    }

    @Override
    public BigDecimal calTotalPrice(Integer userId, Integer[] productIds) {
        List<Object> cartItemList = getAllCartItems(userId);
        BigDecimal totalPrice = new BigDecimal(0);
        for (Object o : cartItemList) {
            CartItem cartItem = (CartItem) o;
            totalPrice = totalPrice.add(cartItem.getSumPrice());
        }
        return totalPrice;
    }
    @Override
    public CartAll calPrice(Integer userId, Integer[] productIds, Boolean excludeOthers) {
        List<Object> cartItems = getAllCartItems(userId);
        HashMap<Integer, CartVo> map = new HashMap<>();
        for (Object o : cartItems) {
            CartItem cartItem = (CartItem) o;
            Product product = productMapper.selectById(cartItem.getProductId());
            Integer storeId = product.getStoreId();
            if (Arrays.asList(productIds).contains(cartItem.getProductId()) || !excludeOthers) {
                if (map.containsKey(storeId)) {
                    map.get(storeId).getCartItemList().add(cartItem);
                } else {
                    List<CartItem> cartItemList = new ArrayList<>();
                    cartItemList.add(cartItem);
                    CartVo cartVo = new CartVo();
                    cartVo.setTotalPrice(new BigDecimal("0"));
                    cartVo.setCartItemList(cartItemList);
                    cartVo.setStoreId(product.getStoreId());
                    Store store = storeMapper.selectById(product.getStoreId());
                    cartVo.setStoreName(store.getStoreName());
                    cartVo.setStoreImg(store.getStoreImg());
                    map.put(storeId, cartVo);
                }
            }
            if (Arrays.asList(productIds).contains(cartItem.getProductId())) {
                map.get(storeId).setTotalPrice(map.get(storeId).getTotalPrice().add(cartItem.getSumPrice()));
            }
        }
        CartAll cartAll = new CartAll();
        BigDecimal sumPrice = new BigDecimal(0);
        for (Map.Entry<Integer, CartVo> entry : map.entrySet()) {
            sumPrice = sumPrice.add(entry.getValue().getTotalPrice());
        }
        cartAll.setTotalPrice(sumPrice);
        cartAll.setCartVoList(new ArrayList<>(map.values()));
        return cartAll;
    }

    /**
     * 购物车购买数量，则返回true
     * @param userId
     * @return
     */
    @Override
    public boolean updateCart(Integer userId) {
        HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
        List<Object> objectList = opsForHash.values(userId + "");
        boolean isUpdated = false;
        for (Object o : objectList) {
            CartItem cartItem = (CartItem) o;

            Product product = productMapper.selectById(cartItem.getProductId());
            //todo 有条件可以想办法提示顾客
            if (product == null || product.getStatus() == 1){
                //如果商品无了,直接删除购物车内容
                opsForHash.delete(userId+"",cartItem.getProductId()+"");
                isUpdated = true;
            }
            else if (product.getStockCount() == 0 && cartItem.getStockCount() != -1){
                //如果商品无了，修改购物车库存为-1，代表失效
                cartItem.setStockCount(-1);
                opsForHash.put(userId+"",cartItem.getProductId()+"",cartItem);
                isUpdated = true;
            }
            else if (product.getStockCount() < cartItem.getBuyCount() && product.getStockCount() != 0){
                cartItem.setBuyCount(product.getStockCount());
                cartItem.setSumPrice(product.getProductPrice().multiply(new BigDecimal(cartItem.getBuyCount())));
                opsForHash.put(userId+"",cartItem.getProductId()+"",cartItem);
                isUpdated = true;
            }
            else if (product.getStockCount() !=  cartItem.getStockCount() && product.getStockCount()> 0 ){
                //如果库存不对，更新数量
                if(cartItem.getStockCount() == -1){
                    isUpdated = true;
                }
                cartItem.setStockCount(product.getStockCount());
                cartItem.setSumPrice(product.getProductPrice().multiply(new BigDecimal(cartItem.getBuyCount())));
                opsForHash.put(userId+"",cartItem.getProductId()+"",cartItem);
            }

        }
        return isUpdated;
    }

    @Override
    public boolean containProductIds(Integer[] productIds,Integer userId) {
        HashOperations<String, Object, Object> opsForHash = redisTemplate.opsForHash();
        for (Integer productId : productIds) {
            if ( opsForHash.get(userId + "", productId + "") == null){
                return false;
            }
        }
        return true;
    }


}
